package com.liqi.web.controller.common.minio;

import io.minio.*;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.util.UUID;

@Slf4j
@Component
@Profile({"dev", "test", "prod","liantiao", "zw"})
public class MinIoService {
	private static final Logger logger = LoggerFactory.getLogger(MinIoService.class);

    @Autowired
    private MinIoProperties minIoProperties;

    private MinioClient minioClient;

    /**
     * 初始化minio配置
     *
     * @param :
     * @return: void
     * @date : 2020/8/16 20:56
     */
    @PostConstruct
    private void init() {
        try {
            minioClient = MinioClient.builder().endpoint(minIoProperties.getUrl()).credentials(minIoProperties.getAccessKey(), minIoProperties.getSecretKey()).build();
            createBucket(minIoProperties.getBucketName());
        } catch (Exception e) {
            e.printStackTrace();
            log.error("初始化minio配置异常:{}", e.getMessage());
        }
    }

    /**
     * 判断 bucket是否存在
     *
     * @param bucketName: 桶名
     * @return: boolean
     * @date : 2020/8/16 20:53
     */
    @SneakyThrows(Exception.class)
    private boolean bucketExists(String bucketName) {
        return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
    }

    /**
     * 创建 bucket
     *
     * @param bucketName: 桶名
     * @return: void
     * @date : 2020/8/16 20:53
     */
    @SneakyThrows(Exception.class)
    private void createBucket(String bucketName) {
        boolean isExist = this.bucketExists(bucketName);
        if (!isExist) {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
        }
    }

    /**
     * 文件上传
     *
     * @param file: 文件
     * @return: java.lang.String : 文件url地址
     * @date : 2020/8/16 23:40
     */
    @SneakyThrows(Exception.class)
    public String upload(MultipartFile file) {
        String fileName = UUID.randomUUID().toString().replace("-", "") + this.getExtendName(file);
        String now = LocalDate.now().toString();
        String year = now.substring(0, 4);
        String month = now.substring(5, 7);
        String day = now.substring(8, 10);
        InputStream inputStream = file.getInputStream();
        fileName = year + "/" + month + "/" + day + "/" + fileName;
        PutObjectArgs args = PutObjectArgs.builder()
                .bucket(minIoProperties.getBucketName())
                .object(fileName)
                .stream(inputStream, file.getSize(), -1)
                .contentType(file.getContentType())
                .build();
        minioClient.putObject(args);
        //return minIoProperties.getUrl() + "/" + minIoProperties.getBucketName() + "/" + fileName;
		if (inputStream!=null) {
			inputStream.close();
		}
        return "/" + minIoProperties.getBucketName() + "/" + fileName;
    }

    // 获取扩展名
    private String getExtendName(MultipartFile file) {
        String filename = file.getOriginalFilename();
        if (!filename.contains(".")) {
            return "";
        }
        int index = filename.lastIndexOf(".");
        return file.getOriginalFilename().substring(index);
    }

    // 获取文件名
    private String getFileName(String fileName) {
        fileName = fileName.replace("http://", "").replace("https://", "");
        int index = fileName.indexOf("/");
        fileName = fileName.substring(index + 1);
        index = fileName.indexOf("/");
        return fileName.substring(index);
    }

    /**
     * 删除文件
     *
     * @param fileName: 文件名
     * @return: void
     * @date : 2020/8/16 20:53
     */
    @SneakyThrows(Exception.class)
    public void deleteFile(String fileName) {
        minioClient.removeObject(RemoveObjectArgs.builder().bucket(minIoProperties.getBucketName()).object(this.getFileName(fileName)).build());
    }

    /**
     * 下载文件
     *
     * @param fileName: 文件名
     * @param response:
     * @return: void
     * @date : 2020/8/17 0:34
     */
    @SneakyThrows(Exception.class)
    public void download(String fileName, HttpServletResponse response) {
        // 获取对象的元数据
        StatObjectResponse stat = minioClient.statObject(StatObjectArgs.builder().bucket(minIoProperties.getBucketName()).object(this.getFileName(fileName)).build());
        response.setContentType(stat.contentType());
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(this.getFileName(fileName), "UTF-8"));
        InputStream is = minioClient.getObject(GetObjectArgs.builder().bucket(minIoProperties.getBucketName()).object(this.getFileName(fileName)).build());
        IOUtils.copy(is, response.getOutputStream());
        is.close();
    }

}
